#pragma once
#include <cstddef>

template <typename T>
struct ControlBlock {
    T* ptr;
    size_t strong_ref;
    size_t weak_ref;

    ControlBlock(T* p) : ptr(p), strong_ref(1), weak_ref(1) {}
};

template <typename T>
class weak_ptr;

template <typename T>
class shared_ptr {
public:
    // 构造函数
    explicit shared_ptr(T* p = nullptr) {
        if (p) {
            ptr = p;
            cb = new ControlBlock<T>(p);
        }
        else {
            ptr = nullptr;
            cb = nullptr;
        }
    }

    ~shared_ptr() {
        if (cb) {
            cb->strong_ref--; // 减少引用计数
            if (cb->strong_ref == 0) {
                // 引用计数为0，释放对象
                delete cb->ptr;
                cb->ptr = nullptr;
            }
            cb->weak_ref--;  // 减少弱引用计数器
            if (cb->weak_ref == 0) {
                delete cb;
            }
            ptr = nullptr;
            cb = nullptr;
        }
    }

    // 拷贝构造，共享所有权，增加引用计数
    shared_ptr(const shared_ptr& other) {
        if (other.cb) {
            ptr = other.ptr;
            cb = other.cb;
            cb->strong_ref++;
        }
        else {
            ptr = nullptr;
            cb = nullptr;
        }
    }

    // 拷贝赋值，释放当前资源，共享新资源
    shared_ptr& operator=(const shared_ptr& other) {
        if (this != &other) {
            if (cb) {
                cb->strong_ref--;
                if (cb->strong_ref == 0) {
                    delete cb->ptr;
                    cb->ptr = nullptr;
                }
                cb->weak_ref--;
                if (cb->weak_ref == 0) {
                    delete cb;
                }
            }
            // 共享新资源
            if (other.cb) {
                ptr = other.ptr;
                cb = other.cb;
                cb->strong_ref++;
            }
            else {
                ptr = nullptr;
                cb = nullptr;
            }
        }
        return *this;
    }

    // 解引用和成员访问
    T& operator*() const { return *ptr; }
    T* operator->() const { return ptr; }

    // 获取原始指针
    T* get() const { return ptr; }    

    // 获取当前强引用计数
    size_t use_count() const { return cb ? cb->strong_ref : 0; }

    // 供weak_ptr访问控制块
    template <typename U>
    friend class weak_ptr;


private:
    T* ptr;
    ControlBlock<T>* cb;
    // 仅用于weak_ptr::lock()：升级弱引用为强引用
    shared_ptr(const weak_ptr<T>& wp) {
        if (wp.cb && wp.cb->strong_ref > 0) {
            ptr = wp.cb->ptr;
            cb = wp.cb;
            cb->strong_ref++; // 增加强引用计数
        } else {
            ptr = nullptr;
            cb = nullptr;
        }
    }
};


template <typename T>
class weak_ptr {
private:
    ControlBlock<T>* cb; // 指向共享的控制块
public:
    // 默认构造
    weak_ptr() : cb(nullptr) {}
    // 从shared_ptr构造：增加弱引用计数
    weak_ptr(const shared_ptr<T>& other) {
        cb = other.cb;
        if (cb) cb->weak_ref++;
    }
    // 拷贝构造：共享控制块，增加弱引用计数
    weak_ptr(const weak_ptr& other) {
        cb = other.cb;
        if (cb) cb->weak_ref++;
    }
    // 析构函数：减少弱引用计数，必要时释放控制块
    ~weak_ptr() {
        if (cb) {
            cb->weak_ref--;
            if (cb->weak_ref == 0) {
                delete cb;
            }
            cb = nullptr;
        }
    }
    // 赋值操作：支持shared_ptr和weak_ptr
    weak_ptr& operator=(const shared_ptr<T>& other) {
        // 释放当前控制块
        if (cb) {
            cb->weak_ref--;
            if (cb->weak_ref == 0) delete cb;
        }
        // 绑定新shared_ptr的控制块
        cb = other.cb;
        if (cb) cb->weak_ref++;
        return *this;
    }
    weak_ptr& operator=(const weak_ptr& other) {
        if (this != &other) {
            // 释放当前控制块
            if (cb) {
                cb->weak_ref--;
                if (cb->weak_ref == 0) delete cb;
            }
            // 绑定新weak_ptr的控制块
            cb = other.cb;
            if (cb) cb->weak_ref++;
        }
        return *this;
    }
    // 升级为shared_ptr（若对象存在）
    shared_ptr<T> lock() const {
        if (cb && cb->strong_ref > 0) { // 确保对象未被释放
            return shared_ptr<T>(*this); // 使用shared_ptr私有构造函数
        }
        return shared_ptr<T>(nullptr); // 对象已释放，返回空
    }
    // 检查对象是否已过期（强引用为0）
    bool expired() const { return use_count() == 0; }
    // 获取强引用计数
    size_t use_count() const { return cb ? cb->strong_ref : 0; }
    // 友元声明：允许shared_ptr从weak_ptr构造
    template <typename U>
    friend class shared_ptr;
};
